﻿using System;
using System.Data.SqlClient;

namespace RepositoryFramework
{
	/// <summary>
	/// Class <see cref="UnitOfWork"/> define database unit of work
	/// </summary>
	public abstract class UnitOfWork : IUnitOfWork, IDisposable
	{
		#region Fields

		private readonly SqlConnection _connection;
		private SqlTransaction _transaction;
		private bool _disposed = false;

		#endregion Fields

		#region Properties

		/// <summary>
		/// Gets the database connection.
		/// </summary>
		/// <value>
		/// The connection.
		/// </value>
		public SqlConnection Connection
		{
			get { return _connection; }
		}

		/// <summary>
		/// Gets the database connection.
		/// </summary>
		/// <value>
		/// The connection.
		/// </value>
		public SqlTransaction Transaction
		{
			get { return _transaction; }
		}

		#endregion Properties

		#region .ctor

		/// <summary>
		/// Initializes a new instance of the <see cref="UnitOfWork"/> class.
		/// </summary>
		/// <param name="connectionString">The connection string.</param>
		public UnitOfWork(string connectionString)
		{
			_connection = new SqlConnection(connectionString);
			_connection.Open();
			_transaction = _connection.BeginTransaction();
		}

		#endregion .ctor

		#region Methods

		/// <summary>
		/// Commit changes
		/// </summary>
		public void Save()
		{
			try
			{
				_transaction.Commit();
			}
			catch
			{
				_transaction.Rollback();
				throw;
			}
			finally
			{
				_transaction.Dispose();
				_transaction = _connection.BeginTransaction();
			}
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!this._disposed)
			{
				if (disposing)
				{
					_transaction.Dispose();
					_connection.Dispose();
				}
			}
			this._disposed = true;
		}

		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		#endregion Methods
	}
}